#include <iostream>
#include <vector>
#include <fstream>
#include <omp.h>

namespace KMeansMultipleOverlapBoundary {

    void
    read_parameter(std::vector<int> &distance_idx, std::vector<int> &single_partition, std::vector<int> &cluster_len
                   , int &n_cluster, int &n_item, char *path) {

        char directory[256];
        std::sprintf(directory, "%s/distance_idx.txt", path);
        std::ifstream instream;
        instream.open(directory, std::ios::in);
        if (!instream.is_open()) {//判断文件是否打开
            std::cout << "Error opening file" << std::endl;
        }
        instream >> n_cluster >> n_item;
        cluster_len.resize(n_cluster);
        for (int i = 0; i < n_cluster; i++) {
            instream >> cluster_len[i];
        }

        distance_idx.resize(n_item);
        for (int i = 0; i < n_item; i++) {
            instream >> distance_idx[i];
        }
        instream.close();

        single_partition.resize(n_item);
        std::sprintf(directory, "%s/single_partition.txt", path);
        instream.open(directory, std::ios::in);
        if (!instream.is_open()) {//判断文件是否打开
            std::cout << "Error opening file" << std::endl;
        }
        for (int i = 0; i < n_item; i++) {
            instream >> single_partition[i];
        }
        instream.close();
    }

    std::vector<std::pair<int, int>>
    get_overlap_partition(std::vector<int> &distance_idx, std::vector<int> &single_partition
                          , std::vector<int> &cluster_len
                          , int *distance_to_centroid_idx, float overlap_proportion) {

        /*
         * the shape of centroid_distance: n_item * n_cluster
         */
        int n_cluster = cluster_len.size();
        int n_item = single_partition.size();

        std::vector<std::pair<int, int>> overlap_partition(n_item);
#pragma omp parallel for
        for (int i = 0; i < n_item; i++) {
            overlap_partition[i].first = single_partition[i];

            //check it is beyond overlap
            int cluster_idx = single_partition[i];
            int sort_idx = distance_idx[i];
            int cluster_size = cluster_len[cluster_idx];
            int *nearest_idx_l = distance_to_centroid_idx + i * n_cluster;
            if (cluster_size * overlap_proportion > sort_idx) {
                overlap_partition[i].second = nearest_idx_l[1]; //the second nearest neighbor
            } else {
                overlap_partition[i].second = nearest_idx_l[0];
            }

        }

//        omp_init_lock(&rootlock);
//        omp_set_lock(&rootlock);
//        omp_unset_lock(&rootlock);
        return overlap_partition;

    }

    void save_overlap_partition(std::vector<std::pair<int, int>> overlap_partition_l, char *path) {
        int n_item = overlap_partition_l.size();
        char directory[256];
        std::ofstream out_partition;
        std::sprintf(directory, "%s/partition.txt", path);
        out_partition.open(directory);
        for (int i = 0; i < n_item; i++) {
            out_partition << overlap_partition_l[i].first << " " << overlap_partition_l[i].second << std::endl;
        }
        out_partition.close();
    }

}